package com.will.seed.websocket;

import io.netty.channel.ChannelHandler;
import lombok.extern.slf4j.Slf4j;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

/**
 * Created by xiaoEight on 2018/8/17.
 */
@Slf4j
@ChannelHandler.Sharable
public class TextWebSocketFrameHandler  extends SimpleChannelInboundHandler<TextWebSocketFrame>{

    @Autowired
    private RedisMessageListenerContainer container;

    @Autowired
    private SyncSender syncSender;

    private final ChannelGroup group;

    public TextWebSocketFrameHandler(ChannelGroup group) {
        this.group = group;
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        Channel channel = ctx.channel();
        String token = channel.attr(Constants.CHANNEL_TOKEN_KEY).get();
        log.info(msg.text());
        //ctx.writeAndFlush(new TextWebSocketFrame("server back msg:" + msg.text()));
        syncSender.pub(token, msg.text());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("Current channel channelInactive");
        offLines(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("Current channel handlerRemoved");
        offLines(ctx);
    }

    private void offLines(ChannelHandlerContext ctx) {
        Channel channel = ctx.channel();
        String token = channel.attr(Constants.CHANNEL_TOKEN_KEY).get();
        log.info(token);

        group.remove(channel);
        SyncReceiver syncReceiver = ChannelManager.getInstance().getReceiverMap().getOrDefault(token,null);
        if(syncReceiver!=null){
            container.removeMessageListener(syncReceiver);
            ChannelManager.getInstance().getReceiverMap().remove(token);
        }
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("=====> {}", cause.getMessage());
        offLines(ctx);
    }
}
